package com.hyd.hx_adr.aspect;

import com.alibaba.fastjson.JSONObject;
import com.hyd.hx_adr.annotations.Auth;
import com.hyd.hx_adr.annotations.PassToken;
import com.hyd.hx_adr.exception.AuthenticationException;
import com.hyd.hx_adr.modules.user.domain.entity.User;
import com.hyd.hx_adr.utils.JWTUtils;
import com.hyd.hx_adr.utils.RedisUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

;

/**
 * AuthenticationInterceptor
 *
 * @author AoMing
 * @since 2022/1/27 14:47
 */

@Slf4j
public class AuthenticationInterceptor implements HandlerInterceptor {

    @Value("${config.tokenName}")
    private String tokenName;

    @Value("${config.expireTime}")
    private Long EXPIRE_TIME;

    @Autowired
    private RedisUtils redisUtils;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader(tokenName);

        if (request.getRequestURI().equals("/error")) return true;

        log.info("URI={}", request.getRequestURI());
        if(!(handler instanceof HandlerMethod)) {
            return true;
        }

        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method method = handlerMethod.getMethod();

        //检查方法是有标有跳过校验的注解
        if (method.isAnnotationPresent(PassToken.class)) {
            PassToken passToken = method.getAnnotation(PassToken.class);
            if (passToken.required()) {
                return true;
            }
        }
        else {

            if(token == null) {
                throw new AuthenticationException("非法请求！");
            }

            String userId;
            try{
                Claims claims = JWTUtils.parseJWT(token);
                // 拿到解析出来的值
                userId = claims.getSubject();
            }
            catch (Exception exception) {
                throw new AuthenticationException("登录已过期，请重新登录");
            }

            Integer t = (Integer) redisUtils.get(userId + "_ACCESS_TOKEN_");
            if (t == null) {
                throw new AuthenticationException("登录已过期，请重新登录");
            }

            String o = (String) redisUtils.get(userId + "_USER_INFO_");
            User userInfo = JSONObject.parseObject(o, User.class);

            if(userInfo == null) {
                throw new AuthenticationException("登录已过期，请重新登录");
            }

//            if (method.isAnnotationPresent(Auth.class)) {
//                Auth auth = method.getAnnotation(Auth.class);
//                if (!userInfo.getPermissions().contains(auth.value())) {
//                    throw new AuthenticationException("您没有权限进行此操作");
//                }
//            }

            log.info("REQUEST_USER-----------------------: {} -- {}", userInfo.getUserName(), userId);

            redisUtils.expire(userId + "_ACCESS_TOKEN_", EXPIRE_TIME);
            redisUtils.expire(userId + "_USER_INFO_", EXPIRE_TIME);
            request.setAttribute("owner", userInfo.getId());
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
